package com.ljh.onlinetest.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ljh.onlinetest.domain.Question;
import com.ljh.onlinetest.domain.TextContent;
import com.ljh.onlinetest.domain.enums.QuestionStatusEnum;
import com.ljh.onlinetest.domain.enums.QuestionTypeEnum;
import com.ljh.onlinetest.domain.question.QuestionItemObject;
import com.ljh.onlinetest.domain.question.QuestionObject;
import com.ljh.onlinetest.repository.BaseMapper;
import com.ljh.onlinetest.repository.QuestionMapper;
import com.ljh.onlinetest.service.QuestionService;
import com.ljh.onlinetest.service.SubjectService;
import com.ljh.onlinetest.service.TextContentService;
import com.ljh.onlinetest.utils.ExamUtil;
import com.ljh.onlinetest.utils.JsonUtil;
import com.ljh.onlinetest.utils.ModelMapperSingle;
import com.ljh.onlinetest.utils.PageInfoHelper;
import com.ljh.onlinetest.viewmodel.admin.question.QuestionEditItemVM;
import com.ljh.onlinetest.viewmodel.admin.question.QuestionEditRequestVM;
import com.ljh.onlinetest.viewmodel.admin.question.QuestionRequestPageVM;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ljh
 * @ClassName QuestionServiceImpl.java
 * @createTime 2022年01月20日
 */
@Service
public class QuestionServiceImpl extends BaseServiceImpl<Question> implements QuestionService {

    private static final ModelMapper modelMapper = ModelMapperSingle.Instance();

    private QuestionMapper questionMapper;
    private TextContentService textContentService;
    private SubjectService subjectService;

    @Autowired
    public QuestionServiceImpl(QuestionMapper questionMapper, TextContentService textContentService, SubjectService subjectService) {
        super(questionMapper);
        this.questionMapper = questionMapper;
        this.textContentService = textContentService;
        this.subjectService = subjectService;
    }

    @Override
    public PageInfo<Question> listPage(QuestionRequestPageVM requestPageVM) {
        return PageHelper.startPage(requestPageVM.getPageIndex(),requestPageVM.getPageSize(),"id desc").doSelectPageInfo(
                () -> {
                    questionMapper.page(requestPageVM);
                });
    }

    @Override
    public QuestionEditRequestVM getQuestionEditRequestVM(Integer id) {
        Question question = questionMapper.selectByPrimaryKey(id);
        return getQuestionEditRequestVM(question);
    }

    @Override
    public QuestionEditRequestVM getQuestionEditRequestVM(Question question) {
        //题目映射，由于题目是html,需要把题目字符串转化成json给前端显示
        TextContent textContent = textContentService.selectById(question.getInfoTextContentId());
        QuestionObject questionObject = JsonUtil.toJsonObject(textContent.getContent(), QuestionObject.class);
        QuestionEditRequestVM vm = modelMapper.map(question, QuestionEditRequestVM.class);
        vm.setTitle(questionObject.getTitleContent());

        //答案
        QuestionTypeEnum questionTypeEnum = QuestionTypeEnum.fromCode(question.getQuestionType());
        switch (questionTypeEnum){
            case SingleChoice:
            case TrueFalse:
                vm.setCorrect(question.getCorrect());
                break;
            case MultipleChoice:
                vm.setCorrectArray(ExamUtil.contentToArray(question.getCorrect()));
                break;
            case GapFilling:
                List<String> collect = questionObject.getQuestionItemObjects().stream().map(d -> d.getContent()).collect(Collectors.toList());
                vm.setCorrectArray(collect);
                break;
            case ShortAnswer:
                vm.setCorrect(questionObject.getCorrect());
                break;
            default:
                break;
        }
        vm.setScore(ExamUtil.scoreToVM(question.getScore()));
        vm.setAnalyze(questionObject.getAnalyze());

        //题目选项映射
        List<QuestionEditItemVM> editItemVMS = questionObject.getQuestionItemObjects().stream().map(o -> {
            QuestionEditItemVM editItemVM = modelMapper.map(o, QuestionEditItemVM.class);
            if (o.getScore() != null){
                editItemVM.setScore(ExamUtil.scoreToVM(o.getScore()));
            }
            return editItemVM;
        }).collect(Collectors.toList());
        vm.setItems(editItemVMS);
        return vm;
    }

    @Override
    @Transactional
    public Question insertFullQuestion(QuestionEditRequestVM vm, Integer userId) {
        Date now = new Date();
        Integer gradeLevel = subjectService.levelBySubjectId(vm.getSubjectId());

        //题干，解析，选项等 插入
        TextContent infoTextContent = new TextContent();
        infoTextContent.setCreateTime(now);
        setQuestionInfoFromVM(infoTextContent,vm);
        textContentService.insertByFilter(infoTextContent);

        Question question = new Question();
        question.setSubjectId(vm.getSubjectId());
        question.setGradeLevel(gradeLevel);
        question.setCreateTime(now);
        question.setCreateUser(userId);
        question.setQuestionType(vm.getQuestionType());
        question.setInfoTextContentId(infoTextContent.getId());
        question.setStatus(QuestionStatusEnum.OK.getCode());
        question.setCorrectFromVM(vm.getCorrect(), vm.getCorrectArray());
        question.setScore(ExamUtil.scoreFromVM(vm.getScore()));
        question.setDifficult(vm.getDifficult());
        question.setDeleted(false);
        questionMapper.insertSelective(question);
        return question;
    }

    @Override
    @Transactional
    public Question updateFullQuestion(QuestionEditRequestVM model) {
        Integer level = subjectService.levelBySubjectId(model.getSubjectId());
        Question question = questionMapper.selectByPrimaryKey(model.getId());
        question.setSubjectId(model.getSubjectId());
        question.setGradeLevel(level);
        question.setScore(ExamUtil.scoreFromVM(model.getScore()));
        question.setDifficult(model.getDifficult());
        //设置正确选项，不包括解析
        question.setCorrectFromVM(model.getCorrect(),model.getCorrectArray());
        questionMapper.updateByPrimaryKeySelective(question);

        //题干，解析，选项等更新
        TextContent textContent = textContentService.selectById(question.getInfoTextContentId());
        setQuestionInfoFromVM(textContent,model);
        textContentService.updateByIdFilter(textContent);
        return question;
    }

    @Override
    public Integer selectAllCount() {
        return questionMapper.selectAllCount();
    }

    private void setQuestionInfoFromVM(TextContent infoTextContent, QuestionEditRequestVM vm) {
        List<QuestionItemObject> itemObjectList = vm.getItems().stream().map(i -> {
            QuestionItemObject questionItemObject = new QuestionItemObject();
            questionItemObject.setPrefix(i.getPrefix());
            questionItemObject.setScore(ExamUtil.scoreFromVM(i.getScore()));
            questionItemObject.setItemUuid(i.getItemUuid());
            questionItemObject.setContent(i.getContent());
            return questionItemObject;
        }).collect(Collectors.toList());

        QuestionObject questionObject = new QuestionObject();
        questionObject.setQuestionItemObjects(itemObjectList);
        questionObject.setAnalyze(vm.getAnalyze());
        questionObject.setTitleContent(vm.getTitle());
        questionObject.setCorrect(vm.getCorrect());
        infoTextContent.setContent(JsonUtil.toJsonStr(questionObject));
    }
}
